from django.conf import settings

from rest_framework import serializers

from prj002.models import (
    clinical, cure, disease, experiment,
    info, standard, summary, history, bxray
)

from utils.samecode import ExtendsSerializer, SCSerializer
from utils.generate import create_dikang_mingan
from utils.savemobile import create_object


class SearchSerializer(serializers.ModelSerializer):
    """ For search api """
    patient_birth = serializers.CharField(required=False, help_text='出生年份')
    career = serializers.CharField(required=False, help_text='职业')
    patient_name = serializers.CharField(required=False, help_text='姓名')
    patient_phone = serializers.CharField(required=False, help_text='手机号')
    hospital_name = serializers.CharField(required=False, help_text='所在医院')
    # address = serializers.CharField(required=False, help_text='地址')
    check_status = serializers.CharField(required=False, help_text='审核状态')

    # 针对用户进行查询
    owner__user_name = serializers.CharField(help_text='医生姓名', required=False)
    owner__hospital = serializers.CharField(help_text='医生所在医院', required=False)

    class Meta:
        model = info.Info
        fields = [
            'patient_name', 'patient_phone', 'hospital_name',
            'patient_birth', 'career', 'check_status',
            'owner__user_name', 'owner__hospital',
        ]


class InfoSerializer(ExtendsSerializer, serializers.ModelSerializer):
    # create_time = serializers.DateTimeField(format=settings.DATETIME_FORMAT, read_only=True)

    class Meta:
        model = info.Info
        # fields = '__all__'
        exclude = ['create_time', 'id']
        read_only_fields = ['serial', 'bmi', 'whr', 'check_status', 'reason_for_check']
        project_name = 'prj002'
        save_mobile = True


class InfoLinkSerializer(ExtendsSerializer, serializers.HyperlinkedModelSerializer, ):
    check = serializers.HyperlinkedIdentityField(read_only=True, view_name='prj002-info-check', lookup_field='pk',)
    info = serializers.HyperlinkedIdentityField(read_only=True, view_name='prj002-info-detail', lookup_field='pk',)
    summary = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-summary-detail')
    standard = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-standard-detail')
    history = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-history-detail')
    experiment = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-experiment-detail')
    bxray = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-bxray-detail')
    cure = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-cure-detail')
    clinical = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-clinical-detail')
    disease = serializers.HyperlinkedRelatedField(read_only=True, view_name='prj002-disease-detail')
    create_time = serializers.DateTimeField(format=settings.DATETIME_FORMAT, read_only=True)
    owner_id = serializers.PrimaryKeyRelatedField(label='辅助医生ID', read_only=True)
    owner_name = serializers.StringRelatedField(label='辅助医生姓名', read_only=True, source='owner.user_name')

    class Meta:
        model = info.Info
        fields = '__all__'
        read_only_fields = ['serial', 'owner', 'bmi', 'whr', 'check_status', 'reason_for_check']
        extra_kwargs = {
            'url': {'view_name': 'prj002-info-detail', 'lookup_field': 'pk'},
        }
        project_name = 'prj002'
        save_mobile = False


class CheckStatusSerializer(serializers.Serializer):
    CHECKED_STATUS = [i[0] for i in info.Info.CHECKED_CHOICE]
    CHECKED_CHOICE = info.Info.CHECKED_CHOICE

    check_status = serializers.ChoiceField(required=True, choices=CHECKED_CHOICE, help_text='审核状态')
    reason_for_check = serializers.CharField(required=False, help_text='审核不通过原因')

    def validate(self, value):
        status = value.get('check_status')
        if status not in self.CHECKED_STATUS:
            raise serializers.ValidationError('非法审核状态')

        reason = value.get('reason_for_check')

        if status == '审核不通过' and not reason:
            raise serializers.ValidationError('审核不通过的原因未填写.')

        return value


class SummarySerializer(serializers.ModelSerializer):

    class Meta:
        model = summary.Summary
        # fields = '__all__'
        exclude = ['owner', 'create_time', 'info', 'id']


class SummaryLinkSerializer(SCSerializer):

    class Meta:
        model = summary.Summary
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-summary-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class DiseaseSerializer(serializers.ModelSerializer):

    class Meta:
        model = disease.Disease
        # fields = '__all__'
        exclude = ['owner', 'create_time', 'info', 'id']


class DiseaseLinkSerializer(SCSerializer):

    class Meta:
        model = disease.Disease
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-disease-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class StandardSerializer(serializers.ModelSerializer):

    class Meta:
        model = standard.Standard
        # fields = '__all__'
        exclude = ['owner', 'create_time', 'info', 'id']


class StandardLinkSerializer(SCSerializer):

    class Meta:
        model = standard.Standard
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-standard-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class ExperimentSerializer(serializers.ModelSerializer):

    class Meta:
        model = experiment.Experiment
        exclude = ['owner', 'create_time', 'info', 'id']
        read_only_fields = ['yidaosu_dikang', 'yidaosu_mingan']

    def create(self, validate_data):
        instance = super().create(validate_data)
        instance = create_dikang_mingan(instance)
        return instance

    def update(self, instance, validate_data):
        for key, value in validate_data.items():
            if hasattr(instance, key):
                setattr(instance, key, value)

        instance.save()

        instance = create_dikang_mingan(instance)
        instance.save()
        return instance


class ExperimentLinkSerializer(SCSerializer):

    class Meta:
        model = experiment.Experiment
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner', 'yidaosu_dikang', 'yidaosu_mingan']
        extra_kwargs = {
            'url': {'view_name': 'prj002-experiment-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }

    def create(self, validate_data):
        instance = super().create(validate_data)
        instance = create_dikang_mingan(instance)
        return instance

    def update(self, instance, validate_data):
        for key, value in validate_data.items():
            if hasattr(instance, key):
                setattr(instance, key, value)

        instance.save()

        instance = create_dikang_mingan(instance)
        return instance


class CureSerializer(serializers.ModelSerializer):

    class Meta:
        model = cure.Cure
        project_name = 'prj002'
        exclude = ['owner', 'create_time', 'info', 'id']


class CureLinkSerializer(SCSerializer):

    class Meta:
        model = cure.Cure
        project_name = 'prj002'
        fields = '__all__'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-cure-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class ClinicalSerializer(serializers.ModelSerializer):

    class Meta:
        model = clinical.Clinical
        exclude = ['owner', 'create_time', 'info', 'id']

        # fields = '__all__'
        # read_only_fields = ['owner']


class ClinicalLinkSerializer(SCSerializer):

    class Meta:
        model = clinical.Clinical
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-clinical-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class BxraySerializer(serializers.ModelSerializer):

    class Meta:
        model = bxray.Bxray
        exclude = ['owner', 'create_time', 'info', 'id']

        # fields = '__all__'
        # read_only_fields = ['owner']


class BxrayLinkSerializer(SCSerializer):

    class Meta:
        model = bxray.Bxray
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-bxray-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class HistorySerializer(serializers.ModelSerializer):

    class Meta:
        model = history.History
        exclude = ['owner', 'create_time', 'info', 'id']

        # fields = '__all__'
        # read_only_fields = ['owner']


class HistoryLinkSerializer(SCSerializer):

    class Meta:
        model = history.History
        fields = '__all__'
        project_name = 'prj002'
        read_only_fields = ['owner']
        extra_kwargs = {
            'url': {'view_name': 'prj002-history-detail', 'lookup_field': 'pk'},
            'info': {'view_name': 'prj002-info-detail', }
        }


class AllSerializer(serializers.Serializer):
    info = InfoSerializer(required=False)
    history = HistorySerializer(required=False)
    bxray = BxraySerializer(required=False)
    clinical = ClinicalSerializer(required=False)
    cure = CureSerializer(required=False)
    experiment = ExperimentSerializer(required=False)
    summary = SummarySerializer(required=False)
    disease = DiseaseSerializer(required=False)
    standard = StandardSerializer(required=False)

    def create(self, instance):
        return instance


class MobileSerializer(serializers.Serializer):
    info = InfoSerializer(required=True)
    history = HistorySerializer(required=False)
    bxray = BxraySerializer(required=False)
    clinical = ClinicalSerializer(required=False)
    cure = CureSerializer(required=False)
    experiment = ExperimentSerializer(required=False)
    summary = SummarySerializer(required=False)
    disease = DiseaseSerializer(required=False)
    standard = StandardSerializer(required=False)

    def create(self, instance):
        info = instance.get('info')
        info_owner = info.pop('owner')
        info['owner'] = info_owner.id

        info_serializer = InfoSerializer(data=info)
        info_serializer.is_valid(raise_exception=True)
        info_instance = info_serializer.save()

        summary = instance.get('summary')
        history = instance.get('history')
        experiment = instance.get('experiment')
        bxray = instance.get('bxray')
        cure = instance.get('cure')
        clinical = instance.get('clinical')
        disease = instance.get('disease')
        standard = instance.get('standard')

        create_object(info_instance, summary, SummarySerializer)
        create_object(info_instance, history, HistorySerializer)
        create_object(info_instance, experiment, ExperimentSerializer)
        create_object(info_instance, bxray, BxraySerializer)
        create_object(info_instance, cure, CureSerializer)
        create_object(info_instance, clinical, ClinicalSerializer)
        create_object(info_instance, disease, DiseaseSerializer)
        create_object(info_instance, standard, StandardSerializer)

        return instance
